# coding=utf-8
"""
Copyright (c) Huawei Technologies Co., Ltd. 2020-2028. All rights reserved.
Description:
FileName：install.py
Author: h00568282/huangbin 
Create Date: 2025/9/18 14:42
Notes:

# get config from mcp-center or third-parth mcp.
# mcp start method
# mcp tool info
# todo install mcp server requirement
"""
import json
import os
import shutil
import subprocess
from pathlib import Path
from typing import Union, Dict

from sys_intd.constant import DEFAULT_LOCAL_MCPS_CONFIG_PATH, PROJECT_MCP_CENTER_PATH
from sys_intd.manager import McpServerManager
from sys_intd.schema import MCPCenterServerConfig, ServerConfig
from .utils import extract_python_cmd
from ..exceptions import MCPServerInstallError

def extract_mcp_config(mcp_server_manager:McpServerManager, server_name: str) -> Dict[str, str]:
    data = {}

    if "mcp" not in server_name:
        server_name = f"{server_name}_mcp"
    mcps_config_path = mcp_server_manager.get_mcp_center_mcps_config_path()
    mcp_config_path = os.path.join(mcps_config_path, server_name)
    if not os.path.exists(mcp_config_path):
        return data

    mcp_config_json = os.path.join(mcp_config_path, "config.json")
    with open(mcp_config_json, 'r', encoding='utf-8') as f:
        data = json.load(f)

    mcps_saved_json = os.path.join(DEFAULT_LOCAL_MCPS_CONFIG_PATH, f"{server_name}.json")
    with open(mcps_saved_json, 'w', encoding='utf-8') as f:
        json.dump(data, f, ensure_ascii=False, indent=4)

    return data


def get_server_config(mcp_server_manager:McpServerManager, server_name: str) -> Union[ServerConfig, None]:
    services_path = mcp_server_manager.get_mcp_center_service_path()
    # get server from mcp center
    try:
        python_cmd = extract_python_cmd(services_path, server_name)
    except FileNotFoundError:
        raise MCPServerInstallError(f"{server_name} server is not found in mcp center.")

    if python_cmd:
        mcp_config: dict = extract_mcp_config(mcp_server_manager, server_name)
        server_config = {
            "name": server_name,
            "command": python_cmd[0],
            "args": python_cmd[1:],
            "env": {},
            "url": mcp_config.get("config", {}).get("url"),
            "headers": {}
        }

        return MCPCenterServerConfig.model_validate(server_config)
    else:
        # todo get mcp server from third mcp center
        raise MCPServerInstallError(f"{server_name} server is not found in mcp center.")


def install(server_name: str):
    output_lines = []
    mcp_server_manager = McpServerManager()
    server_src = os.path.join(PROJECT_MCP_CENTER_PATH, "servers", server_name)
    server_config = get_server_config(mcp_server_manager, server_name)
    if "requirements.txt" in os.listdir(server_src):
        venv_root = Path(f"{server_src}/.venv")
        req_file = Path(f"{server_src}/requirements.txt")
        pip_index = "https://mirrors.huaweicloud.com/repository/pypi/simple"

        # Configure the server
        if venv_root.exists():
            shutil.rmtree(venv_root)

        def run(cmd, **kw):
            """打印+执行，失败把异常信息写进 output_lines 再抛"""
            output_lines.append(f"# {cmd}")
            subprocess.run(cmd, shell=True, check=True, **kw)

        # 1. 创建虚拟环境
        try:
            run(f"python -m venv {venv_root}")
            run(f"source {venv_root}/bin/activate")
            pip = venv_root / "bin" / "pip"
            run(f"{pip} install -r {req_file} -i {pip_index}")
            output_lines.append(f"[bold green]Complete the setup of the MCP server environment.")

        except subprocess.CalledProcessError as e:
            # 捕获到异常，把信息追加到列表
            raise MCPServerInstallError(
                f"[bold red]Command failed (exit {e.returncode})[/]\n"
                f"[bold red]stdout:[/]\n{e.stdout.decode() if e.stdout else ''}\n"
                f"[bold red]stderr:[/]\n{e.stderr.decode() if e.stderr else ''}"
            )

        # 3. 统一赋权
        os.chmod(venv_root, 0o755)
        for dirpath, dirnames, filenames in os.walk(venv_root):
            for d in dirnames:
                os.chmod(os.path.join(dirpath, d), 0o755)
            for f in filenames:
                os.chmod(os.path.join(dirpath, f), 0o644)

    if mcp_server_manager.add_server(server_config):
        output_lines.append(f"[bold green]Installed mcp server: {server_name}[/]")
    else:
        output_lines.append(f"[bold red]Server '{server_config.name}' already exists[/]")
    return output_lines

